/**
 * Copyright 2014  XCL-Charts
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @Project XCL-Charts
 * @Description Android图表基类库
 * @author XiongChuanLiang<br></br>(xcl_168@aliyun.com)
 * @license http://www.apache.org/licenses/  Apache v2 License
 * @version 1.0
 */
package com.gitee.wsl.common.chart.render.shape.bar

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import com.gitee.wsl.android.ui.ext.type.CanvasExt
import com.gitee.wsl.android.ui.ext.type.drawRotateText
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.ui.draw.type.GridDirection
import com.gitee.wsl.math.Math
import com.gitee.wsl.jvm.math.div
import com.gitee.wsl.jvm.math.mul
import com.gitee.wsl.jvm.math.sub
import timber.log.Timber

/**
 * @ClassName Bar
 * @Description  柱形基类，定义了柱形的一些属性
 * @author XiongChuanLiang<br></br>(xcl_168@aliyun.com)
 */
open class Bar {
    //确定是横向柱形还是竖向柱形图
    var barGridDirection = GridDirection.VERTICAL

    var itemLabelStyle = ChartEnum.ItemLabelStyle.NORMAL

    //柱形画笔
    var barPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
              color = Color.rgb(252, 210, 9)
              style = Paint.Style.FILL
           }
    
    //内部柱形
    var outlineBarPaint: Paint  = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        style = Paint.Style.FILL 
    }
   

    //文字画笔
    var itemLabelPaint: Paint  = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        textSize = 12f
        color = Color.BLACK
        textAlign = Paint.Align.CENTER
    }
    
    
    //柱形顶上文字偏移量
    var itemLabelAnchorOffset = 5f

    //柱形顶上文字旋转角度
    var itemLabelRotateAngle = 0.0f

    //是否显示柱形顶上文字标签
    var isShowItemLabel = false

    //柱形间距所占比例
    var barInnerMargin = 0.2f

    //FlatBar类的有效，3D柱形无效
    var barStyle = ChartEnum.BarStyle.GRADIENT

    //柱形所占总比例
    var barTickSpacePercent = 0.7f
    

    //柱子最大宽度
    var barMaxPxWidth = 0.0f

    //柱子最大高度
    var barMaxPxHeight = 0.0f

    //圆柱形的半径
     var barRoundRaidus = 15.0f
     var outlineAlpha = 150
     var borderWidth = 0


    /**
     * 设置所有柱形间占刻度间总空间的百分比(默认为0.7即70%)
     * @param percent 百分比
     */
    fun setBarTickSpacePercent(percent: Float): Boolean {
        if (percent.compareTo(0f) == -1) {
            Timber.d("此比例不能为负数噢!")
            return false
        }
        if (percent.compareTo(0f) == 0) {
            Timber.d("此比例不能等于0!")
            return false
        } else {
            barTickSpacePercent =  percent
        }
        return true
    }

    /**
     * 设置柱形间空白所占的百分比
     * @param percent 百分比
     */
    fun setBarInnerMargin(percent: Float): Boolean {
        if (percent.compareTo(0f) == -1) {
            Timber.d( "此比例不能为负数噢!")
            return false
        }
        if (percent.compareTo(0.9f) == 1 || percent.compareTo(0.9f) == 0) {
            Timber.d("此比例不能大于等于0.9,要给柱形留下点显示空间!")
            return false
        } else {
            barInnerMargin = percent
        }
        return true
    }

    /**
     * 计算同标签多柱形时的Y分隔
     * @param YSteps    Y轴步长
     * @param barNumber  柱形个数
     * @return 返回单个柱形的高度及间距
     */
    protected fun calcBarHeightAndMargin(YSteps: Float, barNumber: Int): FloatArray? {
        if (0 == barNumber) {
            Timber.d( "柱形个数为零.")
            return null
        }
        val labelBarTotalHeight =  Math.mul(YSteps, barTickSpacePercent)
        val barTotalInnerMargin =  Math.mul(labelBarTotalHeight, barInnerMargin)
        val barInnerMargin =  Math.div(barTotalInnerMargin, barNumber.toFloat())
        var barHeight = Math. div( Math.sub(labelBarTotalHeight, barTotalInnerMargin), barNumber.toFloat())
        val ret = FloatArray(2)
        if (barMaxPxHeight.compareTo(0.0f) == 1 && barHeight.compareTo(barMaxPxHeight) == 1) {
            barHeight = barMaxPxHeight
        }
        ret[0] = barHeight
        ret[1] = barInnerMargin
        return ret
    }


    /**
     * 计算同标签多柱形时的X分隔
     * @param XSteps    X轴步长
     * @param barNumber 柱形个数
     * @return 返回单个柱形的宽度及间距
     */
    protected fun calcBarWidthAndMargin(XSteps: Float, barNumber: Int): FloatArray? {
        if (0 == barNumber) {
            Timber.d( "柱形个数为零.")
            return null
        }
        val labelBarTotalWidth =  Math.mul(XSteps, barTickSpacePercent)
        val barTotalInnerMargin =  Math.mul(labelBarTotalWidth, barInnerMargin)
        val barTotalWidth =  Math.sub(labelBarTotalWidth, barTotalInnerMargin)
        val barInnerMargin =  Math.div(barTotalInnerMargin, barNumber.toFloat())
        var barWidth =  Math.div(barTotalWidth, barNumber.toFloat())
        val ret = FloatArray(2)
        if (barMaxPxWidth.compareTo(0.0f) == 1 && barWidth.compareTo(barMaxPxWidth) == 1) {
            barWidth = barMaxPxWidth
        }
        ret[0] = barWidth
        ret[1] = barInnerMargin
        return ret
    }

    /**
     * 绘制柱形顶部标签
     * @param text    内容
     * @param x        x坐标
     * @param y        y坐标
     * @param canvas 画布
     */
    protected fun drawBarItemLabel(text: String, x: Float, y: Float, canvas: Canvas) {
        //在柱形的顶端显示上柱形的当前值			
        if (isShowItemLabel && text.isNotEmpty()) {
            //要依横向还是竖向
            //如果是背向式的，还要看是向上还是向下
            var cx = x
            var cy = y
            when (barGridDirection) {
                GridDirection.VERTICAL -> {
                    val textHeight = CanvasExt.getPaintFontHeight(itemLabelPaint)
                    when (itemLabelStyle) {
                        ChartEnum.ItemLabelStyle.OUTER -> {
                            cy -= itemLabelAnchorOffset
                            cy -= textHeight
                        }
                        ChartEnum.ItemLabelStyle.INNER -> {
                            cy += itemLabelAnchorOffset
                            cy += textHeight
                        }
                        else -> cy -= itemLabelAnchorOffset
                    }
                }
                GridDirection.HORIZONTAL -> {
                    val textWidth = CanvasExt.getTextWidth(itemLabelPaint, text)
                    when (itemLabelStyle) {
                        ChartEnum.ItemLabelStyle.OUTER -> {
                            cx += itemLabelAnchorOffset
                            cx += textWidth
                        }
                        ChartEnum.ItemLabelStyle.INNER -> {
                            cx -= itemLabelAnchorOffset
                            cx -= textWidth
                        }
                        else -> cx += itemLabelAnchorOffset
                    }
                }
            }
            canvas.drawRotateText(
                text,
                cx,
                cy,
                itemLabelRotateAngle,
                itemLabelPaint
            )
        }
    }

}